##########################################
  
  #Name: build.sh
  #Desc: setup java app build env
  #Author OracleGao
  #Email: oraclegao@126.com
  #Date 2019-11-29
  #Git: https://gitee.com/oraclegao/docker-image
  #Origin: 

##########################################

#!/usr/bin/env bash
cd $(dirname $0)

build_path=$(pwd)
build_config=${build_path}/.build

git_branch=master
yml_file=docker-compose.yml

function usage() {
  echo "Usage:"
  echo "  $0 [OPTIONS] <git> "
  echo "  $0 -h | --help"
  echo ""
  echo "OPTIONS:"
  echo "  -b | --branch <string>       git branch (default: ${git_branch}) [init]"
  echo "  -d | --deploy <path>         deploy path, (default: ./) [init]"
  echo "  -D | --debug                 debug mode, show debug message"
  echo "  -h | --help                  show help and exit"
  echo "  -j | --jarname <string>      jar name, (default: pom.xml->project.artifactId) [init]" 
  echo "  -n | --name <string>         service name, (default: git project name) [init]"
  echo "                                 (example: docker-image is the project name of 'https://gitee.com/oraclegao/docker-image.git')"
  echo "  -s | --src <path>            src path, (default: ./src) [init]"
  echo "  -y | --yml <file name>       generated docker compose yml file, if yml file exists, merged (default: ${yml_file}) [init]"
  echo ""
  echo "git:                           clone url of the git code base, (example: https://gitee.com/oraclegao/docker-image.git) [init]"
  echo ""
  exit 1
}

debug_flag=0
for arg in "$@"; do
  if [ "$1" == "" ]; then
    break
  fi
  case $1 in
    -b|--branch)
      git_branch=$2
      shift
      shift
      ;;
    -d|--deploy)
      deploy_path=$2
      shift
      shift
      ;;
    -D|--debug)
      debug_flag=1
      shift
      shift
      ;;
    -h|--help)
      echo "init java app docker image and service build settings"
      echo ""
      usage
      ;;
    -j|--jarname)
      jarname=$2
      shift
      shift
      ;;
    -n|--name)
      service_name=$2
      shift
      shift
      ;;
    -s|--src)
      src_path=$2
      shift
      shift
      ;;
    -y|--yml)
      yml_file=$2
      shift
      shift
      ;;
    *)
      args+=("$1")
      shift
      ;;
  esac
done

if [ "${debug_flag}" == "1" ] ;then
  set -x
fi

xmllint=${build_path}/lib/xmllint

if [ ! -f ${xmllint} ]; then
  curl -L https://gitee.com/oraclegao/docker-image/raw/master/xmllint/xmllint > ${xmllint}
  chmod +x ${xmllint}
fi

if [ -f ${build_config} ]; then
  source ${build_config}
  cd ${JAVA_APP_SRC_PATH}/${JAVA_APP_SERVICE_NAME}
  git pull
  flag=$?
  if [ "$flag" != "0" ]; then
    echo "ERROR:"
    echo "  git pull faild"
    echo ""
    exit 6
  fi
  cd ${build_path}
else
  git_url=${args[0]}
  if [ "${git_url}" == "" ]; then
    echo "ERROR:"
    echo "  git clone url required"
    echo ""
    usage
  fi
  if [ "$service_name" == "" ]; then
    service_name=${git_url##*/}
    if [ "${service_name: -4}" == ".git" ]; then
      service_name=${service_name%.git}
    fi
  fi
  if [ "${deploy_path}" == "" ]; then
    deploy_path=${build_path}
  else
    if [ "${deploy_path:0:1}" != "/" ]; then
      deploy_path=${build_path}/${deploy_path}
    fi
    mkdir -p ${deploy_path}
  fi
  if [ "${src_path}" == "" ]; then
    src_path=${build_path}/src
  else
    if [ "${src_path:0:1}" != "/" ]; then
      src_path=${build_path}/${src_path}
    fi
  fi
  mkdir -p ${src_path}
  if [ ! -f ${src_path}/${service_name}/.git/config ]; then
    git clone ${git_url} -b ${git_branch} ${src_path}/${service_name}
    flag=$?
    if [ "${flag}" != "0" ]; then
      echo "ERROR:"
      echo "  git clone failed"
      exit 2
    fi
  fi

  service_env_name=${service_name//-/_}
  service_env_name=${service_env_name^^}

  if [ -f ${deploy_path}/${yml_file} ]; then
    exist_services=$(docker-compose -f ${deploy_path}/${yml_file} config --service)
    flag=$?
    if [ "${flag}" != "0" ]; then
      echo "ERROR:"
      echo "  invalid docker compose file [${deploy_path}/${yml_file}], merge service failed"
      echo ""
      exit 3
    fi
    for exist_service in ${exist_services}; do
      if [ "${service}" == "${exist_service}" ]; then
        echo "ERROR:"
        echo "  service [${service}] exits in ${deploy_path}/${yml_file}, merge failed"
        echo ""
        exit 4
      fi
    done
  else
    echo "version: '3.2'" >> ${deploy_path}/${yml_file}
    echo ""               >> ${deploy_path}/${yml_file}
    echo "services:"      >> ${deploy_path}/${yml_file}
  fi

  echo "  ${service_name}:"                                                   >> ${deploy_path}/${yml_file}
  echo "    image: ${service_name}:\${${service_env_name}_IMAGE_TAG:-latest}" >> ${deploy_path}/${yml_file}
  echo "    ports: "                                                          >> ${deploy_path}/${yml_file}
  echo "      - \${${service_env_name}_PORT:-8080}:8080"                      >> ${deploy_path}/${yml_file}
  echo "    environment:"                                                     >> ${deploy_path}/${yml_file}
  echo "      SERVER_PORT: 8080"                                              >> ${deploy_path}/${yml_file}
  echo "    env_file:"                                                        >> ${deploy_path}/${yml_file}
  echo "      - ${service_name}.env"                                          >> ${deploy_path}/${yml_file}
  echo "    logging:"                                                         >> ${deploy_path}/${yml_file}
  echo "      options:"                                                       >> ${deploy_path}/${yml_file}
  echo "        max-size: 20mb"                                               >> ${deploy_path}/${yml_file}

cat >> ${build_config} << EOF
export JAVA_APP_SRC_PATH=${src_path}
export JAVA_APP_SERVICE_NAME=${service_name}
export JAVA_APP_DEPLOY_PATH=${deploy_path}
export JAVA_APP_YML_FILE=${yml_file}
export JAVA_APP_GIT_BRANCH=${git_branch}
export JAVA_APP_GIT_URL=${git_url}
EOF

  if [ "${jarname}" != "" ]; then
    echo "export JAVA_APP_JAR_NAME=${jarname}" >> ${build_config}
  fi

  echo "TZ=${JAVA_APP_TIME_ZONE:-Asia/Shanghai}"                                               >> ${deploy_path}/${service_name}.env
  echo "JAVA_OPTS=-Xms128m -Xmx512m -Xss1024K -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m" >> ${deploy_path}/${service_name}.env

  source ${build_config}

fi

if [ "${JAVA_APP_IMAGE_NAME}" == "" ]; then
  JAVA_APP_IMAGE_NAME=${JAVA_APP_SERVICE_NAME}
fi

pom_file=${JAVA_APP_SRC_PATH}/${JAVA_APP_SERVICE_NAME}/pom.xml

project_version=$(${xmllint} -x ${pom_file} --xpath '/*[local-name()="project"]/*[local-name()="version"]/text()')

java_version=$(${xmllint} -x ${pom_file} --xpath '/*[local-name()="project"]/*[local-name()="properties"]/*[local-name()="java.version"]/text()')
if [ "${java_version}" != "" ]; then
  case ${java_version} in
    1.6)
      export JAVA_APP_JAVA_VERSION=6
      ;;
    1.7)
      export JAVA_APP_JAVA_VERSION=7
      ;;
    1.8)
      export JAVA_APP_JAVA_VERSION=8
      ;;
    *)
      export JAVA_APP_JAVA_VERSION=${java_version}
      ;;
  esac 
fi

if [ "${JAVA_APP_IMAGE_TAG}" == "" ]; then
  JAVA_APP_IMAGE_TAG=${project_version}
fi

if [ "${JAVA_APP_JAR_NAME}" == "" ]; then
  project_artifact_id=$(${xmllint} -x ${pom_file} --xpath '/*[local-name()="project"]/*[local-name()="artifactId"]/text()')
  jar_file_name=${project_artifact_id}-${project_version}${JAVA_APP_JAR_POSFIX}.jar
else
  jar_file_name=${JAVA_APP_JAR_NAME}-${project_version}${JAVA_APP_JAR_POSFIX}.jar
fi

docker-compose -f ${build_path}/lib/docker-compose.yml up java-app-compile 
docker-compose -f ${build_path}/lib/docker-compose.yml rm -f java-app-compile

mkdir -p ${build_path}/.tmp
timestamp=$(date "+%Y%m%d%H%M%S")
dockerfile=${build_path}/.tmp/Dockerfile.${timestamp}

jar_file=${JAVA_APP_SRC_PATH}/target/${jar_file_name}
if [ ! -f "${jar_file}" ]; then
  jar_file=$(find ${JAVA_APP_SRC_PATH} -name ${jar_file_name} | head -1)
  if [ "${jar_file}" == "" ]; then
    echo "ERROR:"
    echo "jar file [${jar_file_name}] not found in src path [${JAVA_APP_SRC_PATH}]"
    echo ""
    exit 5
  fi
fi

cp ${jar_file} ${build_path}/.tmp/runnable.jar

cat >> ${dockerfile} << EOF
FROM openjdk:${JAVA_APP_JAVA_VERSION:-11}-jre-slim
LABEL maintainer="oraclegao@126.com"

RUN mkdir -p /opt/jar

WORKDIR /opt/jar

COPY ./lib/entrypoint.sh entrypoint.sh
COPY .tmp/runnable.jar runnable.jar

EXPOSE 8080

CMD ["/opt/jar/entrypoint.sh"]
EOF

docker build -f ${dockerfile} -t ${JAVA_APP_IMAGE_NAME}:${JAVA_APP_IMAGE_TAG} .

service_env_name=${JAVA_APP_SERVICE_NAME//-/_}
service_env_name=${service_env_name^^}

env_file=${JAVA_APP_DEPLOY_PATH}/.env
if [ -f "${env_file}" ]; then
  count=$(grep "^${service_env_name}_IMAGE_TAG" ${env_file} | wc -l)
  if [ $count == 0 ]; then
    echo "${service_env_name}_IMAGE_TAG=${project_version}" >> ${env_file}
  else
    sed -i "s/^${service_env_name}_IMAGE_TAG=.*/${service_env_name}_IMAGE_TAG=${project_version}/" ${env_file}
  fi
else
  echo "${service_env_name}_IMAGE_TAG=${project_version}" >> ${env_file}
fi

rm -rf ./.tmp
docker-compose -f ${build_path}/lib/docker-compose.yml up java-app-cleanup
docker-compose -f ${build_path}/lib/docker-compose.yml rm -f java-app-cleanup

echo "build success"
echo "deploy path [${JAVA_APP_DEPLOY_PATH}]"
echo "src path [${JAVA_APP_SRC_PATH}/${JAVA_APP_SERVICE_NAME}]"
